package com.yixun.qfbao.service.impl;

import com.yixun.common.page.Page;
import com.yixun.qfbao.mapper.CustomerMapper;
import com.yixun.qfbao.model.Customer;
import com.yixun.qfbao.model.dto.CustomerDto;
import com.yixun.qfbao.model.enums.DelFlagEnum;
import com.yixun.qfbao.service.CustomerService;
import com.yixun.qfbao.util.DateUtils;
import com.yixun.qfbao.xf.model.dto.CustomerPremisesDto;
import com.yixun.qfbao.xf.service.CustomerPremisesService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.Calendar;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;


@Slf4j
@Service("customerService")
public class CustomerServiceImpl implements CustomerService {
	
	@Autowired
	private CustomerMapper mapper;
	@Autowired
	private CustomerPremisesService customerPremisesService;

	@Transactional(readOnly = true)
	public Page<Customer> getPageModel(CustomerDto entity,int begin,int end){
		int total = mapper.count(entity);
		List<Customer> rows = mapper.list(entity,begin,end);
		return new Page<>(total, rows);
	}

	public List<Customer> selectListByDto(CustomerDto entity){
		return mapper.selectListByDto(entity);
	}
	
	public Customer selectByDto(CustomerDto entity){
		return mapper.selectByDto(entity);
	}
	
	public Customer selectById(Long id){
		if(Objects.nonNull(id)){
			return mapper.selectByPrimaryKey(id);
		}
		return null;
	}

	public Customer create(Customer entity) {
		entity.setCreateTime(Calendar.getInstance().getTime());
		entity.setDelFlag(DelFlagEnum.UNDEL.getNo());
		mapper.insertSelective(entity);
		return entity;
	}

	public int update(Customer entity) {
		// 修改时必须判断 id 是否为null,否则很危险
		// 如果为null,会修改全部.最终where语句为 (id is not null),没有 id = ???
		if(Objects.isNull(entity.getId())){
			return 0;
		}
		entity.setUpdateTime(Calendar.getInstance().getTime());
		Example example = new Example(Customer.class);
		example.createCriteria()
				.andIsNotNull("id")
				.andEqualTo("id", entity.getId());
		return mapper.updateByExampleSelective(entity, example);
	}

	public int updateByIds(Customer entity, List<Long> updateIds) {
		// 修改时必须判断 id 是否为null,否则很危险
		// 如果为null,会修改全部.最终where语句为 (id is not null),没有 id = ???
		if(CollectionUtils.isEmpty(updateIds)){
			return 0;
		}
		entity.setUpdateTime(Calendar.getInstance().getTime());
		Example example = new Example(Customer.class);
		example.createCriteria()
				.andIsNotNull("id")
				.andIn("id", updateIds);
		return mapper.updateByExampleSelective(entity, example);
	}

	public int saveOrUpdate(Customer entity) {
		if(Objects.nonNull(entity) && Objects.nonNull(entity.getId())){
			return update(entity);
		}else{
			create(entity);
			return 1;
		}
	}

	@Override
	public void addReport2BindCustomer(CustomerPremisesDto entity) {
		Long bindCustomerId = entity.getCustomerId();
		if(Objects.nonNull(bindCustomerId)){
		    return;
        }
        boolean createFlag = true;
        Long staffId = entity.getStaffId();
        String mobile = entity.getMobile();
		CustomerDto customerDto = new CustomerDto();
		customerDto.setAgentId(staffId);
		customerDto.setMainMobile(mobile);
		List<Customer> customerList = selectListByDto(customerDto);
		if(CollectionUtils.isNotEmpty(customerList)){
			createFlag = false;
			Customer baseCustomer = customerList.get(0);
            bindCustomerId = baseCustomer.getId();
			if(Objects.isNull(baseCustomer.getOriginalReport())){
				customerDto = new CustomerDto();
				customerDto.setId(bindCustomerId);
				customerDto.setOriginalReport(entity.getId());
				update(customerDto);
			}
			// 去除重复客户,并变更报备绑定的客户
			filterRepeatCustomer(customerList, baseCustomer);
		}
		// 创建客户
		if(createFlag){
			Customer addCustomer = new Customer();
			addCustomer.setAgentCompany(entity.getStaffCompanyId());
			addCustomer.setAgentId(staffId);
			addCustomer.setOriginalReport(entity.getId());
			addCustomer.setRealName(entity.getName());
			addCustomer.setGender(entity.getGender());
			addCustomer.setMainMobile(mobile);
			addCustomer.setDelFlag(DelFlagEnum.UNDEL.getNo());
			addCustomer = create(addCustomer);
			bindCustomerId = addCustomer.getId();
		}
		// 报备绑定客户
		CustomerPremisesDto cpDto = new CustomerPremisesDto();
		cpDto.setId(entity.getId());
		cpDto.setCustomerId(bindCustomerId);
		customerPremisesService.updateStatus(cpDto);
	}

	public void filterRepeatCustomer(List<Customer> customerList, Customer bindCustomer){
		// 不存在或只有唯一的客户时,无需处理
		if(customerList.size() <= 1 || Objects.isNull(bindCustomer)){
			return;
		}
		// 与当前绑定客户不一致的其他客户
		List<String> repeatCustomerList = customerList.stream()
				// 保证要去除的客户手机号与已绑定的手机号是一致的.
				// 保证都是同一个经纪人.
				// 三种保障,降低客户被错误变更的几率
				.filter(item -> !item.getId().equals(bindCustomer.getId())
						&& item.getMainMobile().equals(bindCustomer.getMainMobile())
						&& item.getAgentId().equals(bindCustomer.getAgentId()))
				.map(item -> String.valueOf(item.getId()))
				.collect(Collectors.toList());
		// 将重复客户绑定的报备关联客户ID统一改成 bindCustomerId
		if(CollectionUtils.isNotEmpty(repeatCustomerList)){
			CustomerPremisesDto customerPremisesDto = new CustomerPremisesDto();
			customerPremisesDto.setCustomerId(bindCustomer.getId());
			customerPremisesDto.setCustomerIds(repeatCustomerList);
			customerPremisesService.updateCustomerByCustomerIds(customerPremisesDto);
			log.info("change customerids: {} to customerId: {}", repeatCustomerList, bindCustomer.getId());

			// 删除重复客户记录
			Example example = new Example(Customer.class);
			Example.Criteria criteria = example.createCriteria();
			criteria.andIn("id", repeatCustomerList);

			Customer updateCustomer = new Customer();
			updateCustomer.setDelFlag(DelFlagEnum.DEL.getNo());
			updateCustomer.setUpdateTime(DateUtils.getCurrentTS());
			mapper.updateByExampleSelective(updateCustomer, example);
		}
	}

	@Override
	public List<CustomerDto> selectRepeatCustomerList() {
		return mapper.selectRepeatCustomerList();
	}
}
